<?php
/**
 * PhpStorm
 * User: zucheng
 * Date: 2019/3/27
 */

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Api\ApiController;
use App\Library\Common;
use App\Messages\ShippingStatus0Driver;
use App\Messages\ShippingStatus0Order;
use App\Models\Driver;
use App\Models\Member;
use App\Models\MsgFee;
use App\Models\Order;
use App\Models\OwnerRoutes;
use App\Models\Shipping;
use App\Services\MemberService;
use App\Services\NotificationService;
use App\Services\PayService;
use App\Services\RouteService;
use App\Services\ShippingService;
use App\Services\UmengService;
use App\Traits\PayHelper;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
use Validator;
use Illuminate\Http\Request;

class PayController extends ApiController
{
    use PayHelper;

    /**
     * APP支付发起接口
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function msgFeePayByApp(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'order_no'  => 'required',
                'payment'   => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            // 服务费
            $amount = config('pay.msg_amount');
            $amount = $amount * 100; // 元转换为分

            // 支付前校验
            $order = Order::where('order_no', $request->get('order_no'))->firstOrFail();

            $msgFee = MsgFee::onWriteConnection()
                ->where('order_id', $order->id)
                ->where('driver_uuid', $request->get('user_uuid'))
                ->first();
            if ($msgFee) {
                if ($msgFee->pay_status > MsgFee::PAYWAIT) {
                    throw new \Exception('请勿重复支付');
                }
                // 调用第三方接口 查询当前订单支付状态
                $tradeNo = PayService::getInstance()->findPayStatus($msgFee->out_trade_no, $msgFee->payment);

                // 如果订单已经支付完成 修改状态并返回提示
                if ($tradeNo == true) {
                    // 更新支付状态
                    $msgFee->pay_status = MsgFee::PAYED;
                    $msgFee->save();

                    // 运单补偿
                    $shippingData = [
                        'driver_uuid' => $msgFee->driver_uuid,
                        'order_id'    => $msgFee->order_id,
                        'msg_fee_id'  => $msgFee->id,
                    ];
                    ShippingService::getInstance()->createShipping($shippingData);

                    throw new \Exception('已经支付成功，请勿重复支付');
                }

                // 如果订单还未支付，修改支付方式，重新调用支付接口
                $msgFee->payment   = $request->get('payment');
                $msgFee->total_fee = $amount;
                $msgFee->save();

                $data = [
                    'payment'      => $request->get('payment'),
                    'out_trade_no' => $msgFee->out_trade_no,
                    'total_fee'    => $amount,
                    'subject'      => $msgFee->subject,
                ];
            } else {
                $data   = [
                    'order_id'     => $order->id,
                    'driver_uuid'  => $request->get('user_uuid'),
                    'payment'      => $request->get('payment'),
                    'out_trade_no' => Common::createTradeNo(),
                    'total_fee'    => $amount,
                    'subject'      => '信息费支付',
                    'pay_status'   => MsgFee::PAYWAIT,
                ];
                $msgFee = MsgFee::create($data);
            }

            // 支付请求
            $payRet = PayService::getInstance()->payByApp($data['payment'], $data['out_trade_no'], $data['total_fee'], $data['subject']);
            if ($payRet == false) {
                throw new \Exception('支付发起失败');
            }

            //++++++@start - 发送通知，运单状态为0
            $oShipper      = Member::query()->where('uuid', $order->sender_uuid)->firstOrFail();
            $oDriver       = Member::query()->where('uuid', $request->get('user_uuid'))->firstOrFail();

            // @step1 发送通知给司机
            $routeInfo   = RouteService::getInstance()->getDetailedAddressByRouteId($order->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);
            $srcAddress  = $routeInfo['srcDetail'];
            $dstAddress  = $routeInfo['dstDetail'];
            $senderPhone = MemberService::getPhoneByUuid($order->sender_uuid);
            $ownerPhone  = MemberService::getPhoneByUuid($order->owner_uuid);
            $msgContent  = sprintf('接单成功，请及时通知，发货地址：%s，收货地址：%s。请在约定发货时间前往发货地联系发货人，电话：%s，收货人电话：%s',
                $srcAddress,
                $dstAddress,
                $senderPhone,
                $ownerPhone
            );

            $params  = [];
            if ($oDriver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params                                  = [
                    'alias_type'  => 'user_alias',
                    'alias'       => $request->get('user_uuid'),
                    "ticker"      => "接单成功",
                    "title"       => "接单成功",
                    "text"        => $msgContent,
                    "after_open"  => "go_app",
                    "description" => "接单成功",
                ];
                $params['payload']['extra']['cust_type'] = 2; // type：2 跳转站内信页面
            }
            if ($oDriver->user_platform == Member::USER_PLATFORM_IOS) {
                $params                         = [
                    'alert'       => [
                        'title' => '接单成功',
                        'body'  => $msgContent,
                    ],  //字符串或者JSON
                    'alias_type'  => 'user_alias',
                    'alias'       => $request->get('user_uuid'),
                    "description" => '接单成功',
                ];
                $params['payload']['cust_type'] = 2; // type：2 跳转站内信页面
            }
            NotificationService::fire($request->get('user_uuid'), $params, new ShippingStatus0Driver(
                $srcAddress,
                $oShipper->name,
                $senderPhone
            ));

            // @step2 发送通知给发单人
            $oDriverDetail   = Driver::query()->where('uuid', $request->get('user_uuid'))->firstOrFail();
            $driverName      = $oDriver->name;
            $driverPhone     = $oDriver->phone;
            $driverPlate     = $oDriverDetail->car_no;
            $driverOrderTime = date('Y年m月d日H:i:s');
            $msgContent      = sprintf('有新司机接单，司机名字：%s，电话：%s，车牌：%s，目的地为：%s，接单时间：%s',
                $driverName,
                $driverPhone,
                $driverPlate,
                $dstAddress,
                $driverOrderTime
            );

            $params   = [];
            $oCreator = Member::query()->where('uuid', $order->create_uuid)->firstOrFail();
            if ($oCreator->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type'  => 'user_alias',
                    'alias'       => $order->create_uuid,
                    "ticker"      => "有新司机接单",
                    "title"       => "有新司机接单",
                    "text"        => $msgContent,
                    "after_open"  => "go_app",
                    "description" => "有新司机接单",
                ];
            }
            if ($oCreator->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert'       => [
                        'title' => '有新司机接单',
                        'body'  => $msgContent,
                    ],  //字符串或者JSON
                    'alias_type'  => 'user_alias',
                    'alias'       => $order->create_uuid,
                    "description" => '有新司机接单',
                ];
            }
            NotificationService::fire($order->create_uuid, $params, new ShippingStatus0Order(
                $driverName,
                $driverPhone,
                $driverPlate,
                $dstAddress
            ));
            //++++++@end - 发送通知结束


            return $this->success('success', [
                'out_trade_no' => $data['out_trade_no'],
                'pay_request'  => $payRet,
            ]);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 小程序支付发起接口
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function msgFeePayByMiniapp(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_uuid' => 'required|size:36',
                'order_no'  => 'required',
                'payment'   => 'required|integer',
                'openid'    => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            // 服务费
            $amount = config('pay.msg_amount');
            $amount = $amount * 100; // 元转换为分

            // 支付前校验
            $order = Order::where('order_no', $request->get('order_no'))->firstOrFail();

            $msgFee = MsgFee::where('order_id', $order->id)
                ->where('driver_uuid', $request->get('user_uuid'))
                ->first();
            if ($msgFee) {
                if ($msgFee->pay_status > MsgFee::PAYWAIT) {
                    throw new \Exception('请勿重复支付');
                }
                // 调用第三方接口 查询当前订单支付状态
                $tradeNo = PayService::getInstance()->findPayStatus($msgFee->out_trade_no, $msgFee->payment);

                // 如果订单已经支付完成 修改状态并返回提示
                if ($tradeNo == true) {
                    $msgFee->pay_status = MsgFee::PAYED;
                    $msgFee->save();

                    // 运单补偿
                    $shippingData = [
                        'driver_uuid' => $msgFee->driver_uuid,
                        'order_id'    => $msgFee->order_id,
                        'msg_fee_id'  => $msgFee->id,
                    ];
                    ShippingService::getInstance()->createShipping($shippingData);

                    throw new \Exception('已经支付成功，请勿重复支付');
                }

                // 如果订单还未支付，修改支付方式，重新调用支付接口
                $msgFee->payment   = $request->get('payment');
                $msgFee->total_fee = $amount;
                $msgFee->save();

                $data = [
                    'payment'      => $request->get('payment'),
                    'out_trade_no' => $msgFee->out_trade_no,
                    'total_fee'    => $amount,
                    'subject'      => $msgFee->subject,
                ];
            } else {
                $data   = [
                    'order_id'     => $order->id,
                    'driver_uuid'  => $request->get('user_uuid'),
                    'payment'      => $request->get('payment'),
                    'out_trade_no' => Common::createTradeNo(),
                    'total_fee'    => $amount,
                    'subject'      => '信息费支付',
                    'pay_status'   => MsgFee::PAYWAIT,
                ];
                $msgFee = MsgFee::create($data);
            }

            // 调用支付请求
            $payRet = PayService::getInstance()->payByMiniapp($data['payment'], $data['out_trade_no'], $data['total_fee'], $data['subject'], $request->get('openid'));
            if ($payRet == false) {
                throw new \Exception('支付发起失败');
            }

            return $this->success('success', [
                'out_trade_no' => $data['out_trade_no'],
                'pay_request'  => $payRet,
            ]);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 支付结果查询
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function queryPayResult(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'out_trade_no' => 'required'
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $msgFee = MsgFee::onWriteConnection()
                ->where('out_trade_no', $request->get('out_trade_no'))
                ->firstOrFail();

            // 判断支付状态
            if ($msgFee->pay_status != MsgFee::PAYED) {
                // 调用第三方接口 查询当前订单支付状态
                $tradeNo = PayService::getInstance()->findPayStatus($msgFee->out_trade_no, $msgFee->payment);
                if ($tradeNo != true) {
                    throw new \Exception('还未支付成功');
                }

                // 如果订单已经支付完成 修改状态并返回提示
                $msgFee->pay_status = MsgFee::PAYED;
                $msgFee->save();

                // 运单补偿
                $shippingData = [
                    'driver_uuid' => $msgFee->driver_uuid,
                    'order_id'    => $msgFee->order_id,
                    'msg_fee_id'  => $msgFee->id,
                ];
                ShippingService::getInstance()->createShipping($shippingData);
            } else {
                // 运单检测和补偿
                $shippingData = [
                    'driver_uuid' => $msgFee->driver_uuid,
                    'order_id'    => $msgFee->order_id,
                    'msg_fee_id'  => $msgFee->id,
                ];
                ShippingService::getInstance()->createShipping($shippingData);
            }

            // 返回shipping_no
            $oShipping = Shipping::query()
                ->where('order_id', $msgFee->order_id)
                ->where('msg_fee_id', $msgFee->id)
                ->where('driver_uuid', $msgFee->driver_uuid)
                ->first();

            return $this->success('success', [
                'shipping_no' => $oShipping->shipping_no ?? '',
            ]);

        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 阿里app支付同步返回结果验证
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function alipayReturnVerify(Request $request)
    {
        try {
            $this->alipayReturn();

            return $this->success('验证通过');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

}